package com.lwm.service.impl;

import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lwm.domain.MaterialCategory;
import com.lwm.domain.ResponseResult;
import com.lwm.mapper.MaterialCategoryMapper;
import com.lwm.service.MaterialCategoryService;
import com.lwm.utils.Code;
import com.lwm.utils.HintMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 物料分类业务层
 */
@Service
@Slf4j
public class MaterialCategoryServiceImpl implements MaterialCategoryService {
    @Resource
    private MaterialCategoryMapper materialCategoryMapper;

    // TODO 删除该分类做的处理
    //  1. 该分类是否为其他分类的父分类 √
    //  2. 该分类是否被某一物料信息所引用
    //  3. 删除某一物料分类后，需要对分类编码进行处理 TM1223 拼接上 - 和 id => TM123-xx... √

    /**
     * 新增物料分类
     *
     * @param materialCategory 物料分类
     * @return {@link ResponseResult}<{@link Object}>
     */
    @Override
    public ResponseResult<Object> save(MaterialCategory materialCategory) {
        if (!StringUtils.hasText(materialCategory.getCategoryEncoding()) ||
                !StringUtils.hasText(materialCategory.getCategoryName())) {
            return new ResponseResult<>(Code.SAVE_ERR, HintMessage.MUST_PARAM_HINT);
        }
        materialCategory.setId(IdUtil.getSnowflakeNextId());//设置id
        materialCategoryMapper.insert(materialCategory);
        return new ResponseResult<>(Code.SAVE_OK, HintMessage.SAVE_OK_HINT);
    }

    /**
     * 删除物料分类
     *
     * @param ids id组
     * @return {@link ResponseResult}<{@link Object}>
     */
    @Override
    public ResponseResult<Object> remove(List<Long> ids) {
        if (ids.isEmpty()) {
            return new ResponseResult<>(Code.DELETE_ERR, HintMessage.REMOVE_LACK_ID + "物料分类");
        }
        // 该分类为其他分类的父分类，重置掉对应分类的父分类id
        resetParentId(ids);
        // 处理分类编码
        handlerData(ids);
        int i = materialCategoryMapper.deleteByIds(ids);
        if (i <= 0) new ResponseResult<>(Code.DELETE_ERR, HintMessage.REMOVE_ERR_HINT);
        return new ResponseResult<>(Code.DELETE_OK, HintMessage.REMOVE_OK_HINT);
    }

    /**
     * 数据处理
     * 对于分类编码进行处理
     * 如：TM1223 拼接上 - 和 雪花id => TM123-xx...
     *
     * @param ids id集合
     */
    @Override
    public void handlerData(List<Long> ids) {
        log.info("删除前-处理分类编码");
        // 遍历出id
        ids.forEach(id -> {
            MaterialCategory category = materialCategoryMapper.selectById(id);
            // 有效避免空指针
            if (!Objects.isNull(category)) {
                category.setCategoryEncoding(category.getCategoryEncoding()
                        + "-" + IdUtil.getSnowflakeNextId());
                materialCategoryMapper.update(category);
            }

        });
    }

    /**
     * 重置父级id
     *
     * @param ids id集合
     */
    @Override
    public void resetParentId(List<Long> ids) {
        log.info("待重置父级的物料分类id {}", ids);
        for (Long id : ids) {
            List<MaterialCategory> list = materialCategoryMapper.selectParentById(id);
            // 空数据，跳出当前循环，可有效避免空指针
            if (list.isEmpty()) continue;
            // 遍历list集合，置空对应的父级id
            for (MaterialCategory category : list) {
                category.setParentCategoryId(null);
                materialCategoryMapper.update(category);
            }
        }
    }

    /**
     * 编辑
     *
     * @param materialCategory 物料分类
     * @return {@link ResponseResult}<{@link Object}>
     */
    @Override
    public ResponseResult<Object> edit(MaterialCategory materialCategory) {
        if (null == materialCategory.getId()) {// 没有传入分类id
            return new ResponseResult<>(Code.UPDATE_ERR, HintMessage.EDIT_LACK_ID + "物料分类");
        }
        // TODO 前端传递的 分类id 和 父级分类id 一致，需要将 父级分类id 置空掉，
        //  毕竟，默认情况下， 父级分类为空，便是顶级分类
        if (materialCategory.getId().equals(materialCategory.getParentCategoryId())) {
            log.info("分类id 和 父级分类id 一致, 置空 父级分类id");
            materialCategory.setParentCategoryId(null);
        }
        int i = materialCategoryMapper.update(materialCategory);
        if (i <= 0) return new ResponseResult<>(Code.UPDATE_ERR, HintMessage.EDIT_ERR_HINT);
        return new ResponseResult<>(Code.UPDATE_OK, HintMessage.EDIT_OK_HINT);
    }

    /**
     * 编辑批处理
     *
     * @param list 物料分类集合
     * @return {@link ResponseResult}<{@link Object}>
     */
    @Override
    public ResponseResult<Object> editBatch(List<MaterialCategory> list) {
        list.forEach(item -> {
            // 分类id 和 父级分类id 一致，置空父级id
            if (item.getId().equals(item.getParentCategoryId())) {
                log.info("分类id 和 父级分类id 一致, 置空 父级分类id");
                item.setParentCategoryId(null);
            }
        });
        int i = materialCategoryMapper.updateBatch(list);
        if (i <= 0) return new ResponseResult<>(Code.UPDATE_ERR, HintMessage.EDIT_ERR_HINT);
        return new ResponseResult<>(Code.UPDATE_OK, HintMessage.EDIT_OK_HINT);
    }

    /**
     * 分页
     *
     * @param page             当前页
     * @param size             数据量
     * @param materialCategory 物料分类
     * @return {@link ResponseResult}<{@link PageInfo}<{@link MaterialCategory}>>
     */
    @Override
    public ResponseResult<PageInfo<MaterialCategory>> page(Integer page, Integer size, MaterialCategory materialCategory) {
        // 默认页码和默认数量
        if (page == null) page = 1;
        if (size == null) size = 5;

        PageInfo<MaterialCategory> pageInfo = PageHelper
                .startPage(page, size)
                .doSelectPageInfo(() -> materialCategoryMapper.selectAll(materialCategory));
        return new ResponseResult<>(Code.GET_OK, HintMessage.GET_OK_HINT, pageInfo);
    }

    /**
     * 根据id获取
     *
     * @param id 分类id
     * @return {@link ResponseResult}<{@link MaterialCategory}>
     */
    @Override
    public ResponseResult<MaterialCategory> getById(Long id) {
        // 未传id值
        if (null == id) {
            return new ResponseResult<>(Code.GET_ERR, HintMessage.GET_LACK_ID + "物料分类");
        }
        MaterialCategory category = materialCategoryMapper.selectById(id);
        // 没有该id对应的数据
        if (Objects.isNull(category)) return new ResponseResult<>(Code.GET_ERR, HintMessage.GET_ERR_HINT);

        return new ResponseResult<>(Code.GET_OK, HintMessage.GET_OK_HINT, category);
    }

    /**
     * 获取对应id是否作为其他分类的父级而存在
     *
     * @param ids id集合
     * @return {@link ResponseResult}<{@link Object}>
     */
    @Override
    public ResponseResult<Object> getParentExist(List<Long> ids) {
        if (ids.isEmpty()) {
            return new ResponseResult<>(Code.GET_ERR, HintMessage.GET_LACK_ID + "物料分类");
        }
        // 统计数量
        int count = 0;
        // 遍历id
        for (Long id : ids) {
            // 执行查询，查询该分类是否已经作为其他分类的父分类
            List<MaterialCategory> list = materialCategoryMapper.selectParentById(id);
            // 已经作为其他分类的父分类
            if (list.isEmpty()) {
                continue;
            }
            count++;
        }
        if (count > 0) {
            return new ResponseResult<>(Code.GET_OK,
                    "待删除的分类数据中，已有作为其他分类的父分类，" +
                            "确定删除之后，会重置对应其他分类的父分类哦");
        }
        return new ResponseResult<>(Code.GET_OK, "没有关联");
    }
}
